/* Copyright 2010 OddRain
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.oddrain.wifieditor;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

public class WifiConfigList extends Activity implements
		OnSharedPreferenceChangeListener {

	protected static final int SHOW_PREFERENCES = 0;
	private WifiManager wifi;
	private ListView wifiConfigListView;
	private List<WifiConfiguration> wifiConfigList;
	private WifiConfiguration selectedConfig;
	private WifiConfigurationAdapter aa;
	private boolean editingPrefs = false;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		// Setup WiFi
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		wifiConfigListView = (ListView) findViewById(R.id.wifiConfigList);

		wifiConfigListView.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> _av, View _v, int _index,
					long arg3) {
				selectedConfig = wifiConfigList.get(_index);

				// Populate Preferences
				Context context = getApplicationContext();
				SharedPreferences prefs = PreferenceManager
						.getDefaultSharedPreferences(context);
				prefs.registerOnSharedPreferenceChangeListener(WifiConfigList.this);
				SharedPreferences.Editor editor = prefs.edit();
				editor.clear();

				if (selectedConfig.SSID != null
						&& selectedConfig.SSID.length() >= 2) {
					editor.putString(WifiConfigSettings.PREF_SSID,
							selectedConfig.SSID.substring(1,
									selectedConfig.SSID.length() - 1));
				}
				editor.putBoolean(WifiConfigSettings.PREF_HIDDEN_SSID,
						selectedConfig.hiddenSSID);

				editor.putBoolean(WifiConfigSettings.PREF_KEY_NONE,
						selectedConfig.allowedKeyManagement
								.get(WifiConfiguration.KeyMgmt.NONE));
				editor.putBoolean(WifiConfigSettings.PREF_KEY_PSK,
						selectedConfig.allowedKeyManagement
								.get(WifiConfiguration.KeyMgmt.WPA_PSK));
				editor.putBoolean(WifiConfigSettings.PREF_KEY_EAP,
						selectedConfig.allowedKeyManagement
								.get(WifiConfiguration.KeyMgmt.WPA_EAP));
				editor.putBoolean(WifiConfigSettings.PREF_KEY_IEEE,
						selectedConfig.allowedKeyManagement
								.get(WifiConfiguration.KeyMgmt.IEEE8021X));

				editor.putBoolean(WifiConfigSettings.PREF_AUTH_OPEN,
						selectedConfig.allowedAuthAlgorithms
								.get(WifiConfiguration.AuthAlgorithm.OPEN));
				editor.putBoolean(WifiConfigSettings.PREF_AUTH_LEAP,
						selectedConfig.allowedAuthAlgorithms
								.get(WifiConfiguration.AuthAlgorithm.LEAP));
				editor.putBoolean(WifiConfigSettings.PREF_AUTH_SHARED,
						selectedConfig.allowedAuthAlgorithms
								.get(WifiConfiguration.AuthAlgorithm.SHARED));

				editor.putBoolean(WifiConfigSettings.PREF_SEC_WPA,
						selectedConfig.allowedProtocols
								.get(WifiConfiguration.Protocol.WPA));
				editor.putBoolean(WifiConfigSettings.PREF_SEC_RSN,
						selectedConfig.allowedProtocols
								.get(WifiConfiguration.Protocol.RSN));

				editor.putBoolean(WifiConfigSettings.PREF_PAIR_NONE,
						selectedConfig.allowedPairwiseCiphers
								.get(WifiConfiguration.PairwiseCipher.NONE));
				editor.putBoolean(WifiConfigSettings.PREF_PAIR_CCMP,
						selectedConfig.allowedPairwiseCiphers
								.get(WifiConfiguration.PairwiseCipher.CCMP));
				editor.putBoolean(WifiConfigSettings.PREF_PAIR_TKIP,
						selectedConfig.allowedPairwiseCiphers
								.get(WifiConfiguration.PairwiseCipher.TKIP));

				editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP40,
						selectedConfig.allowedGroupCiphers
								.get(WifiConfiguration.GroupCipher.WEP40));
				editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP104,
						selectedConfig.allowedGroupCiphers
								.get(WifiConfiguration.GroupCipher.WEP104));
				editor.putBoolean(WifiConfigSettings.PREF_GRP_TKIP,
						selectedConfig.allowedGroupCiphers
								.get(WifiConfiguration.GroupCipher.TKIP));
				editor.putBoolean(WifiConfigSettings.PREF_GRP_CCMP,
						selectedConfig.allowedGroupCiphers
								.get(WifiConfiguration.GroupCipher.CCMP));

				if (selectedConfig.wepKeys[0] != null
						&& selectedConfig.wepKeys[0].length() >= 2) {
					editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY0,
							selectedConfig.wepKeys[0].substring(1,
									selectedConfig.wepKeys[0].length() - 1));
				}

				if (selectedConfig.wepKeys[1] != null
						&& selectedConfig.wepKeys[1].length() >= 2) {
					editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY1,
							selectedConfig.wepKeys[1].substring(1,
									selectedConfig.wepKeys[1].length() - 1));
				}

				if (selectedConfig.wepKeys[2] != null
						&& selectedConfig.wepKeys[2].length() >= 2) {
					editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY2,
							selectedConfig.wepKeys[2].substring(1,
									selectedConfig.wepKeys[2].length() - 1));
				}

				if (selectedConfig.wepKeys[3] != null
						&& selectedConfig.wepKeys[3].length() >= 2) {
					editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY3,
							selectedConfig.wepKeys[3].substring(1,
									selectedConfig.wepKeys[3].length() - 1));
				}
				
				if (selectedConfig.preSharedKey != null
						&& selectedConfig.preSharedKey.length() >= 2) {
					editor.putString(WifiConfigSettings.PREF_WPA_KEY,
							selectedConfig.preSharedKey.substring(1,
									selectedConfig.preSharedKey.length() - 1));
				}

				editor.commit();
				editingPrefs = true;

				// Display Preferences
				Intent i = new Intent(context, WifiConfigSettings.class);
				i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
				startActivityForResult(i, SHOW_PREFERENCES);

			}
		});

		wifiConfigList = new ArrayList<WifiConfiguration>();
		int resID = R.layout.wificonfiguration_item;
		aa = new WifiConfigurationAdapter(this, resID, wifiConfigList);
		wifiConfigListView.setAdapter(aa);

		Context context = getApplicationContext();
		context.registerReceiver(new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				loadWifiConfigs();
				System.out.println("Recieved wifi state changed action:"
						+ intent);
			}
		}, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));

		checkWifiState();
	}

	private void loadWifiConfigs() {
		wifiConfigList.clear();
		List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
		for (WifiConfiguration config : configs) {
			wifiConfigList.add(config);
		}
		aa.notifyDataSetChanged();
	}

	private void checkWifiState() {
		boolean enabled = wifi.isWifiEnabled();
		if (!enabled) {
			Builder builder = new AlertDialog.Builder(this);
			builder.setTitle(getString(R.string.app_name));
			builder.setIcon(android.R.drawable.ic_dialog_alert);
			builder.setMessage(getString(R.string.WIFI_ENABLE_MSG));
			builder.setPositiveButton(getString(R.string.YES), new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					wifi.setWifiEnabled(true);
				}
			});
			builder.setNegativeButton(getString(R.string.NO), null);
			builder.show();
		} else {
			loadWifiConfigs();
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		checkWifiState();
		editingPrefs = false;
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		if (editingPrefs) {
			// Save
			saveWiFiConfig();
		}
	}

	private void saveWiFiConfig() {
		// Save Wifi Config from Preferences
		Context context = getApplicationContext();
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);

		if (prefs.getString(WifiConfigSettings.PREF_SSID, null) != null) {
			selectedConfig.SSID = "\""
					+ prefs.getString(WifiConfigSettings.PREF_SSID, "") + "\"";
		}

		if (prefs.getBoolean(WifiConfigSettings.PREF_HIDDEN_SSID, false)) {
			selectedConfig.hiddenSSID = true;
		}

		selectedConfig.allowedKeyManagement.clear();
		if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_IEEE, false)) {
			selectedConfig.allowedKeyManagement
					.set(WifiConfiguration.KeyMgmt.IEEE8021X);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_PSK, false)) {
			selectedConfig.allowedKeyManagement
					.set(WifiConfiguration.KeyMgmt.WPA_PSK);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_EAP, false)) {
			selectedConfig.allowedKeyManagement
					.set(WifiConfiguration.KeyMgmt.WPA_EAP);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_NONE, false)) {
			selectedConfig.allowedKeyManagement
					.set(WifiConfiguration.KeyMgmt.NONE);
		}

		// GroupCiphers
		selectedConfig.allowedGroupCiphers.clear();
		if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP40, false)) {
			selectedConfig.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.WEP40);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP104, false)) {
			selectedConfig.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.WEP104);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_CCMP, false)) {
			selectedConfig.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.CCMP);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_TKIP, false)) {
			selectedConfig.allowedGroupCiphers
					.set(WifiConfiguration.GroupCipher.TKIP);
		}

		// PairwiseCiphers
		selectedConfig.allowedPairwiseCiphers.clear();
		if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_TKIP, false)) {
			selectedConfig.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.TKIP);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_CCMP, false)) {
			selectedConfig.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.CCMP);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_NONE, false)) {
			selectedConfig.allowedPairwiseCiphers
					.set(WifiConfiguration.PairwiseCipher.NONE);
		}

		// Authentication Algorithms
		selectedConfig.allowedAuthAlgorithms.clear();
		if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_OPEN, false)) {
			selectedConfig.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.OPEN);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_SHARED, false)) {
			selectedConfig.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.SHARED);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_LEAP, false)) {
			selectedConfig.allowedAuthAlgorithms
					.set(WifiConfiguration.AuthAlgorithm.LEAP);
		}

		// Protocols
		selectedConfig.allowedProtocols.clear();
		if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_RSN, false)) {
			selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
		}
		if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_WPA, false)) {
			selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
		}

		// WEP Keys
		if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, null) != null) {
			selectedConfig.wepKeys[0] = "\""
					+ prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, "")
					+ "\"";
		}
		if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, null) != null) {
			selectedConfig.wepKeys[1] = "\""
					+ prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, "")
					+ "\"";
		}
		if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, null) != null) {
			selectedConfig.wepKeys[2] = "\""
					+ prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, "")
					+ "\"";
		}
		if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, null) != null) {
			selectedConfig.wepKeys[3] = "\""
					+ prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, "")
					+ "\"";
		}

		if (prefs.getString(WifiConfigSettings.PREF_WPA_KEY, null) != null) {
			selectedConfig.preSharedKey = "\""
					+ prefs.getString(WifiConfigSettings.PREF_WPA_KEY, "")
					+ "\"";
		}

		wifi.updateNetwork(selectedConfig);
		wifi.enableNetwork(selectedConfig.networkId, false);
		wifi.saveConfiguration();
	}
}